These forms make let-like
bindings to functions instead of variables.
This form establishes
let-style bindings on the function cells of symbols rather than on the value cells. Each binding must be a list of the form ‘(name arglist forms...)’, which defines a function exactly as if it were adefun*form. The function name is defined accordingly for the duration of the body of theflet; then the old function definition, or lack thereof, is restored.While
fletin Common Lisp establishes a lexical binding of name, Emacs Lispfletmakes a dynamic binding. The result is thatfletaffects indirect calls to a function as well as calls directly inside thefletform itself.You can use
fletto disable or modify the behavior of a function in a temporary fashion. This will even work on Emacs primitives, although note that some calls to primitive functions internal to Emacs are made without going through the symbol's function cell, and so will not be affected byflet. For example,(flet ((message (&rest args) (push args saved-msgs))) (do-something))This code attempts to replace the built-in function
messagewith a function that simply saves the messages in a list rather than displaying them. The original definition ofmessagewill be restored afterdo-somethingexits. This code will work fine on messages generated by other Lisp code, but messages generated directly inside Emacs will not be caught since they make direct C-language calls to the message routines rather than going through the Lispmessagefunction.Also note that many primitives (e.g.
+) have special byte-compile handling. Attempts to redefine such functions usingfletwill fail if byte-compiled. In such cases, uselabelsinstead.Functions defined by
fletmay use the full Common Lisp argument notation supported bydefun*; also, the function body is enclosed in an implicit block as if bydefun*. See Program Structure.
The
labelsform is likeflet, except that it makes lexical bindings of the function names rather than dynamic bindings. (In true Common Lisp, bothfletandlabelsmake lexical bindings of slightly different sorts; since Emacs Lisp is dynamically bound by default, it seemed more appropriate forfletalso to use dynamic binding. Thelabelsform, with its lexical binding, is fully compatible with Common Lisp.)Lexical scoping means that all references to the named functions must appear physically within the body of the
labelsform. References may appear both in the body forms oflabelsitself, and in the bodies of the functions themselves. Thus,labelscan define local recursive functions, or mutually-recursive sets of functions.A “reference” to a function name is either a call to that function, or a use of its name quoted by
quoteorfunctionto be passed on to, say,mapcar.